package com.zenithmind.mall.service.impl;

import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.mall.mapper.CouponMapper;
import com.zenithmind.mall.mapper.UserCouponMapper;
import com.zenithmind.mall.pojo.entity.Coupon;
import com.zenithmind.mall.pojo.entity.UserCoupon;
import com.zenithmind.mall.service.CouponUsageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 优惠券使用服务实现类 - 遵循单一职责原则，专门负责优惠券的使用和退还操作
 * 
 * @author ZenithMind Team
 * @since 2025-07-03
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CouponUsageServiceImpl implements CouponUsageService {

    private final CouponMapper couponMapper;
    private final UserCouponMapper userCouponMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean useCoupon(String userCouponId, String orderId) {
        UserCoupon userCoupon = userCouponMapper.selectById(userCouponId);
        if (userCoupon == null) {
            throw new BusinessException("用户优惠券不存在");
        }
        
        if (userCoupon.getStatus() != 0) {
            throw new BusinessException("优惠券状态异常，无法使用");
        }
        
        // 检查优惠券是否可用
        Coupon coupon = couponMapper.selectById(userCoupon.getCouponId());
        if (coupon == null || !coupon.isAvailable()) {
            throw new BusinessException("优惠券不可用");
        }
        
        // 更新用户优惠券状态
        userCoupon.setStatus(1); // 已使用
        userCoupon.setUseTime(LocalDateTime.now());
        userCoupon.setOrderId(orderId);
        
        if (userCouponMapper.updateById(userCoupon) <= 0) {
            throw new BusinessException("使用优惠券失败");
        }
        
        // 增加优惠券使用数量
        coupon.increaseUsedCount();
        couponMapper.updateById(coupon);
        
        log.info("使用优惠券成功: userCouponId={}, orderId={}", userCouponId, orderId);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean returnCoupon(String userCouponId) {
        UserCoupon userCoupon = userCouponMapper.selectById(userCouponId);
        if (userCoupon == null) {
            throw new BusinessException("用户优惠券不存在");
        }
        
        if (userCoupon.getStatus() != 1) {
            throw new BusinessException("优惠券状态异常，无法退还");
        }
        
        // 更新用户优惠券状态
        userCoupon.setStatus(0); // 未使用
        userCoupon.setUseTime(null);
        userCoupon.setOrderId(null);
        
        if (userCouponMapper.updateById(userCoupon) <= 0) {
            throw new BusinessException("退还优惠券失败");
        }
        
        // 减少优惠券使用数量
        Coupon coupon = couponMapper.selectById(userCoupon.getCouponId());
        if (coupon != null && coupon.getUsedCount() != null && coupon.getUsedCount() > 0) {
            coupon.setUsedCount(coupon.getUsedCount() - 1);
            couponMapper.updateById(coupon);
        }
        
        log.info("退还优惠券成功: userCouponId={}", userCouponId);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean useCoupons(List<String> userCouponIds, String orderId) {
        for (String userCouponId : userCouponIds) {
            if (!useCoupon(userCouponId, orderId)) {
                throw new BusinessException("批量使用优惠券失败: " + userCouponId);
            }
        }
        
        log.info("批量使用优惠券成功: userCouponIds={}, orderId={}", userCouponIds, orderId);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean returnCoupons(List<String> userCouponIds) {
        for (String userCouponId : userCouponIds) {
            if (!returnCoupon(userCouponId)) {
                throw new BusinessException("批量退还优惠券失败: " + userCouponId);
            }
        }
        
        log.info("批量退还优惠券成功: userCouponIds={}", userCouponIds);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean lockCoupon(String userCouponId, String orderId) {
        UserCoupon userCoupon = userCouponMapper.selectById(userCouponId);
        if (userCoupon == null) {
            throw new BusinessException("用户优惠券不存在");
        }
        
        if (userCoupon.getStatus() != 0) {
            throw new BusinessException("优惠券状态异常，无法锁定");
        }
        
        // 更新用户优惠券状态为锁定
        userCoupon.setStatus(2); // 锁定状态
        userCoupon.setOrderId(orderId);
        
        if (userCouponMapper.updateById(userCoupon) <= 0) {
            throw new BusinessException("锁定优惠券失败");
        }
        
        log.info("锁定优惠券成功: userCouponId={}, orderId={}", userCouponId, orderId);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean unlockCoupon(String userCouponId) {
        UserCoupon userCoupon = userCouponMapper.selectById(userCouponId);
        if (userCoupon == null) {
            throw new BusinessException("用户优惠券不存在");
        }
        
        if (userCoupon.getStatus() != 2) {
            throw new BusinessException("优惠券状态异常，无法解锁");
        }
        
        // 更新用户优惠券状态为未使用
        userCoupon.setStatus(0); // 未使用
        userCoupon.setOrderId(null);
        
        if (userCouponMapper.updateById(userCoupon) <= 0) {
            throw new BusinessException("解锁优惠券失败");
        }
        
        log.info("解锁优惠券成功: userCouponId={}", userCouponId);
        return true;
    }

    @Override
    public Boolean isCouponLocked(String userCouponId) {
        UserCoupon userCoupon = userCouponMapper.selectById(userCouponId);
        return userCoupon != null && userCoupon.getStatus() == 2;
    }
}
